package org.ucas.faker.web.utils.mql.parse;


import org.ucas.faker.web.utils.mql.domain.Condition;
import org.ucas.faker.web.utils.mql.domain.Where;

public class WordTreeVisitor extends MqlBaseVisitor<Where> {

  private MqlParser.IdFieldExprContext current;

  private MqlParser.CondContext parent;

  public WordTreeVisitor(MqlParser.IdFieldExprContext current, MqlParser.CondContext parent) {
    this.current = current;
    this.parent = parent;
  }

  @Override
  public Where visitParWordExpr(MqlParser.ParWordExprContext ctx) {
    return visit(ctx.wordExpr());
  }

  @Override
  public Where visitAtomWordExpr(MqlParser.AtomWordExprContext ctx) {
    if (parent instanceof MqlParser.ContainsCondContext) {
      String word = ctx.getText();
      Condition cond = new Condition(current.getText(), Condition.OPEAR.CONTAINS, word.substring(1, word.length() - 1));
      MqlParser.ContainsCondContext tmp = (MqlParser.ContainsCondContext) parent;
      if (tmp.FLOAT() != null) cond.setBoost(Float.parseFloat(tmp.FLOAT().getText()));
      return cond;
    } else
      return null;
  }

  @Override
  public Where visitAndWordExpr(MqlParser.AndWordExprContext ctx) {
    Where res = new Where(Where.CONN.AND);
    ctx.wordExpr().forEach(c -> {
      Where cond = visit(c);
      if (cond == null) return;
      if (cond.getBoost() != null) {
        res.setBoost(res.getBoost() == null ? cond.getBoost() : Math.max(res.getBoost(), cond.getBoost()));
      }
      res.addWhere(cond);
    });
    return res;
  }

  @Override
  public Where visitOrWordExpr(MqlParser.OrWordExprContext ctx) {
    Where res = new Where(Where.CONN.OR);
    ctx.wordExpr().stream().forEach(c -> {
      Where cond = visit(c);
      if (cond == null) return;
      if (cond.getBoost() != null) {
        res.setBoost(res.getBoost() == null ? cond.getBoost() : Math.max(res.getBoost(), cond.getBoost()));
      }
      res.addWhere(cond);
    });
    return res;
  }

  @Override
  public Where visitNotWordExpr(MqlParser.NotWordExprContext ctx) {
    Where res = new Where(Where.CONN.NOT);
    Where cond = visit(ctx.wordExpr());
    res.addWhere(cond);
    res.setBoost(cond.getBoost());
    return res;
  }
}
